/**
 * 地块绘制工具
 */
import Base from "./Base";
import MapCommon from "../../common/MapCommon";
import _ from "lodash"
import MapboxDraw from "@mapbox/mapbox-gl-draw";
import * as turf from '@turf/turf'
import mapboxgl from "mapbox-gl";



export default class ClickEdit extends Base {
  /**
   *
   * @param map
   * @param callBack
   * @param errorCallBack
   * @param clickLayers
   * @param feature
   * @param clickLayersFilters
   * @param isFill 传入的图层是否是面类型
   */
  constructor(map, {callBack: callBack, errorCallBack: errorCallBack, clickLayers: clickLayers, feature = null, clickLayersFilters = [],isFill=false}) {
    super(map, 'ClickEdit', {callBack: callBack, errorCallBack: errorCallBack});
    this.clickLayers = [];//点击查询的图层
    for (let i = 0; i < clickLayers.length; i++) {
      if(!isFill){
        MapCommon.copyLineToAreaFit(this.map, clickLayers[i], clickLayers[i] + "_select");
        this.clickLayers.push(clickLayers[i] + "_select");
      }else {
        this.clickLayers.push(clickLayers[i] );
      }
    }

    //已选择要素集
    this.clickLayersFilters = clickLayersFilters;
    //传入的需要编辑的要素
    this.oldFeature=feature;
    this.isFill=isFill;
  }

  start() {
    super.start();

    if(!this.oldFeature){//未传入要素，点选
      //将所有点击线图层转化为面图层
      this.clickEvent = (e) => {
        this.select([e.originalEvent.layerX, e.originalEvent.layerY])
        e.originalEvent.preventDefault()
      }

      //添加点击事件
      this.map.on('click', this.clickEvent);
    }else {//传入要素则直接编辑
      this.edit(this.oldFeature)
    }

  }

  /**
   * 通过点查询用户点击的面要素
   * @param point
   */
  select(point) {
    if (this.clickLayers.length === 0) {
      return;
    }
    let renderFeatures = this.map.queryRenderedFeatures(point, {layers: this.clickLayers});
    if (!renderFeatures || renderFeatures.length === 0) {
      return;
    }

    //确定优先选中的要素
    let priorityRenderF = this.getPriorityRenderFeature(renderFeatures);

    //避免地块被切片分割的问题
    let features = this.map.querySourceFeatures(priorityRenderF.layer.source, {
      'sourceLayer': priorityRenderF.layer.source,
      'filter': ['==', 'objectid', priorityRenderF.properties.objectid]
    });
    let temp = MapCommon.unionFeatures(features);
    temp.properties = priorityRenderF.properties;
    temp.source = priorityRenderF.source;
    temp.sourceLayer = priorityRenderF.sourceLayer;
    temp.layer = priorityRenderF.layer;

    this.edit(temp);
  }

  //更新source
  edit(feature) {
    this.draw = new MapboxDraw({
        displayControlsDefault: false,
        controls: {}
      }
    );
    this.map.addControl(this.draw);
    let ids = this.draw.set({
      type: 'FeatureCollection',
      features: [feature]
    });
    this.featureId = ids[0];
    if(!this.oldFeature){
      this.map.off('click', this.clickEvent);
      this.clickEvent = null;
    }

    this.draw.changeMode(this.draw.modes.DIRECT_SELECT, {featureId: this.featureId});

    this.updateEvent = (e) => {
      this.update(e)
    };

    this.map.on('draw.update', this.updateEvent);

    this.createEvent = (e) => {
      let feature = this.draw.get(this.featureId);
      //检测自相交
      let featureSet = turf.kinks(feature);
      if (featureSet.features.length > 0) {
        this.error("多边形自相交");
      } else {
        this.finish(feature)
      }
    };
    this.map.on('draw.modechange', this.createEvent);
  }

  /**
   * 移除长度文字
   */
  clearPopup() {
    if (this.popup) {
      this.popup.remove();
      this.popup = null;
      super.clearPopup();
    }
  }

  update(e) {
    this.clearPopup();
    let area = turf.area(e.features[0]);
    let center = turf.center(e.features[0]);

    this.popup = new mapboxgl.Popup({
      closeButton: false,
      closeOnClick: false,
      className: this.popupClassName
    });
    this.popup.setLngLat(center.geometry.coordinates)
      .setText((area * 0.0015).toFixed(2) + "亩")
      .addTo(this.map);
  }

  //获取优先级高的图层要素
  getPriorityRenderFeature(features) {
    let priority = null;
    for (let i = 0; i < this.clickLayers.length; i++) {
      let index = _.findIndex(features, (renderF) => {
        if (renderF.layer.id === this.clickLayers[i]) {
          let filters = this.clickLayersFilters.filter(item =>{
          if(this.isFill){
            return (item.layer) === renderF.layer.id
          }else {
            return (item.layer + "_select") === renderF.layer.id
          }}
          );
          if (filters.length === 0) {
            return true;
          }

          let filter = filters[0];

          if (renderF.properties && renderF.properties[filter.key] && renderF.properties[filter.key] == filter.value) {
            return false
          } else {
            return true;
          }
        } else {
          return false;
        }
      });

      if (index > -1) {
        priority = JSON.parse(JSON.stringify(features[index]));
        break
      }
    }
    return priority
  }


  close(notClearMap = false) {
    this.clear(notClearMap);
    this.clearEvent();
  }

  clear(notClearMap = false) {
    this.clearPopup();
    this.clearMap(notClearMap);
  }

  clearMap(notClearMap = false) {
    //不清除地图选择绘制图层
    if (!notClearMap) {
      super.clearMap();
    }
    if(!this.isFill){
    for (let i = 0; i < this.clickLayers.length; i++) {
      if (this.map.getLayer(this.clickLayers[i])) {
        this.map.removeLayer(this.clickLayers[i]);
      }
    }}
    if(this.draw){
      this.draw.deleteAll();
    }
  }

  clearEvent() {
    super.clearEvent();
    if (this.clickEvent) {
      this.map.off('click', this.clickEvent);
      this.clickEvent = null
    }
    if (this.updateEvent) {
      this.map.off('draw.update', this.updateEvent);
      this.updateEvent = null
    }
    if (this.createEvent) {
      this.map.off('draw.modechange', this.createEvent);
      this.createEvent = null
    }

    this.clickLayers = [];
    if(this.draw){
      this.map.removeControl(this.draw);
      this.draw=null;
    }
  }

  /**
   * 手动关闭
   */
  closeByHand(){
    if(this.draw){
      this.draw.changeMode(this.draw.modes.SIMPLE_SELECT);
      if(this.createEvent){
        this.createEvent();
      }
    }
  }
  /**
   * 获取当前要素
   */
  getCurFeatures(){
    if(this.draw&&this.featureId){
      return[this.draw.get(this.featureId)] ;
    }else {
      return[]
    }
  }
}
